package main

import (
	"encoding/json"
	"log"
	"os"
	"strings"

	"github.com/hu17889/go_spider/core/common/page"
)

var dict map[string]struct {
	Rank    int
	Chinese string
} = map[string]struct {
	Rank    int
	Chinese string
}{
	"score":          {1, "得分"},
	"rank":           {2, "排名"},
	"defeat":         {3, "击败百分比"},
	"platformType":   {4, "平台类型"},
	"showName":       {5, "处理器名称"},
	"coreSpeed":      {6, "处理器频率"},
	"maxSpeed":       {7, "处理器最高频率"},
	"coreNum":        {8, "内核数"},
	"threadNum":      {9, "线程数"},
	"1stCache":       {10, "一级缓存"},
	"2ndCache":       {11, "二级缓存"},
	"3rdCache":       {12, "三级缓存"},
	"tdp":            {13, "热设计功耗"},
	"memoryChannels": {14, "最大内存通道数"},
	"memoryType":     {15, "内存类型"},
	"kernel":         {16, "核心代号"},
	"launchDate":     {17, "发行日期"},
	"launchPrice":    {18, "首发价格"},
	"series":         {19, "系列"},
	"socket":         {20, "插槽类型"},
	"urlkey":         {21, "urlkey"},
}

var processorInfo map[string][]string

type LuDaShiProcessor struct{}

func init() {
	processorInfo = make(map[string][]string)
}

func processCommaString(str string) string {
	if strings.Contains(str, ",") {
		return "\"" + str + "\""
	}

	return str
}

func toString(val interface{}) string {
	switch t := val.(type) {
	case json.Number:
		return t.String()
	case string:
		return t
	default:
		log.Printf("未知类型：%#v", val)
	}

	return ""
}

func fillInfo(platformType, cores, urlkey string, m map[string]interface{}) {
	if _, ok := processorInfo[urlkey]; !ok {
		processorInfo[urlkey] = make([]string, len(dict)-3+3*3)
	}

	for field, item := range dict {
		if field == "score" || field == "rank" || field == "defeat" {
			if cores == "" { // 综合
				processorInfo[urlkey][item.Rank-1] = processCommaString(toString(m[field]))
			} else if cores == "single" { // 单核
				processorInfo[urlkey][item.Rank+3-1] = processCommaString(toString(m[field]))
			} else if cores == "multi" { // 多核
				processorInfo[urlkey][item.Rank+2*3-1] = processCommaString(toString(m[field]))
			}
		} else if field == "platformType" {
			processorInfo[urlkey][item.Rank+3*3-3-1] = processCommaString(platformType)
		} else {
			processorInfo[urlkey][item.Rank+3*3-3-1] = processCommaString(toString(m[field]))
		}
	}
}

func NewLuDaShiProcessor() *LuDaShiProcessor {
	return &LuDaShiProcessor{}
}

func (t *LuDaShiProcessor) Process(p *page.Page) {
	if !p.IsSucc() {
		log.Printf("Err: %s", p.Errormsg())
		return
	}

	j := p.GetJson()
	status := j.Get("status").MustInt()
	msg := j.Get("msg").MustString()
	log.Printf("status: %d, msg: %s", status, msg)

	if status == 1 {
		tag := p.GetUrlTag()
		parts := strings.Split(tag, "|")

		data := j.Get("data").MustArray()
		for _, item := range data {
			log.Printf("item: %#v", item)

			if m, ok := item.(map[string]interface{}); ok {
				urlkey := toString(m["urlkey"])
				fillInfo(parts[0], parts[1], urlkey, m)
			}
		}
	}
}

func (t *LuDaShiProcessor) Finish() {
	log.Println("处理完毕！！！")

	f, err := os.OpenFile("./ludashi.csv", os.O_CREATE|os.O_RDWR, 0644)
	assertErr(err)

	columns := make([]string, len(dict)-3)
	for _, item := range dict {
		if item.Rank < 4 {
			continue
		}

		columns[item.Rank-3-1] = item.Chinese
	}

	f.Write([]byte{0xef, 0xbb, 0xbf}) //UTF-8 BOM
	f.WriteString("综合得分,综合排名,综合击败百分比," +
		"单核得分,单核排名,单核击败百分比," +
		"多核得分,多核排名,多核击败百分比," +
		strings.Join(columns, ",") + "\n")

	for _, info := range processorInfo {
		f.WriteString(strings.Join(info, ",") + "\n")
	}

	f.Close()
}
